import { Collection, MongoClient, ServerApiVersion } from "mongodb";
import { User } from "../models/auth";
import { IGdp, IInfo } from "../models/business";
import { IGdpRes } from "../models/gdp-res";
import { ISmsCodeCache } from "../models/sms-code-cache";
import { IWxToken } from "../models/wx-token";
import { IInfoRes } from "../models/info-res";
import { randomInt } from "crypto";


export class DbService {
    _client: MongoClient;

    async init() {
        if (this._client == null) {
            this._client = new MongoClient(process.env.MONGO_DB_URL ?? "mongodb://localhost:27017/NodejsDemo", {
                serverApi: ServerApiVersion.v1,
            });
            await this._client.connect();

            this.users = <Collection<User>><unknown>await this.getCollection("users");
            this.gdps = <Collection<IGdp>><unknown>await this.getCollection("gdps");
            this.infos = <Collection<IInfo>><unknown>await this.getCollection("infos");
            this.smsCodeCaches = <Collection<ISmsCodeCache>><unknown>await this.getCollection("smsCodeCaches");
            this.wxTokens = <Collection<IWxToken>><unknown>await this.getCollection("wxTokens");
            this.gdpRes = <Collection<IGdpRes>><unknown>await this.getCollection("gdpRes");
            this.infoRess = <Collection<IInfoRes>><unknown>await this.getCollection("infoRess");

            this.users.createIndex({ createdAt: 1 }, { expireAfterSeconds: 7200 });
            this.smsCodeCaches.createIndex({ createdAt: 1 }, { expireAfterSeconds: 600 });
            this.gdpRes.createIndex({ createdAt: 1 }, { expireAfterSeconds: 24 * 60 * 60 });
            this.infoRess.createIndex({ createdAt: 1 }, { expireAfterSeconds: 600 });

            this.smsCodeCaches.createIndex({ userId: 1 });
            this.users.createIndex({ wxOpenId: 1 });
            this.users.createIndex({ mob: 1 });

            if (await db.infos.estimatedDocumentCount() == 0) {
                for (let i = 1; i <= 100; i++)
                    await db.infos.insertOne(
                        {
                            name: `信息${i}`,
                            detail: i % 3 == 0 ? `这是一条比较长的信息${i}内容，用作展示两列不对称效果` : `信息${i}内容`,
                            contact: `某某${i}`,
                            createdAt: new Date()
                        });
            }

            // 插入gdp模拟数据
            if (await db.gdps.estimatedDocumentCount() == 0) {
                for (let i = 2001; i <= 2024; i++)
                    await db.gdps.insertOne(
                        {
                            year: i,
                            amount: 10000 + randomInt(10, 1000),
                            growthRate: randomInt(-10, 10) * 0.01,
                        });
            }
        }
    }

    /**
     * @param collectionName 
     * @param dbName 
     * @returns 
     */
    getCollection(collectionName: string, dbName: string = "NodejsDemo") {
        let database = this._client.db(dbName);
        let collection = database.collection(collectionName);
        return collection;
    }

    users: Collection<User>;
    gdps: Collection<IGdp>;
    infos: Collection<IInfo>;
    smsCodeCaches: Collection<ISmsCodeCache>;
    wxTokens: Collection<IWxToken>;
    gdpRes: Collection<IGdpRes>;
    infoRess: Collection<IInfoRes>;

}

export const db = new DbService();

await db.init();